<

SwiftUI 開発者向けの Flutter

Flutter を使用してモバイル アプリを作成したい SwiftUI 開発者 このガイドを確認する必要があります。 既存の SwiftUI の知識を Flutter に適用する方法について説明します。

Flutter はクロスプラットフォーム アプリケーションを構築するためのフレームワークです Dart プログラミング言語を使用します。 Dart を使用したプログラミングのいくつかの違いを理解するには Swift を使用したプログラミングについては、を参照してください。Swift 開発者として Dart を学ぶとSwift 開発者向けの Flutter 同時実行性

SwiftUI の知識と経験 Flutter を使用して構築する場合、これらは非常に価値があります。

Flutter は多くの調整も行います iOS および macOS で実行するときのアプリの動作に影響します。 その方法については、を参照してください。プラットフォームの適応

このドキュメントは、飛び回ってクックブックとして使用できます。 自分のニーズに最も関連する質問を見つけます。 このガイドにはサンプルコードが埋め込まれています。 DartPad で完全な動作例をテストしたり、GitHub で表示したりできます。

概要

Flutter と SwiftUI のコードは、UI の外観と動作を説明します。 開発者はこのタイプのコードを「宣言型フレームワーク

ビューとウィジェット

SwiftUIUIコンポーネントを次のように表しますビュー。 ビューを設定するには、次を使用します。修飾子

Text("Hello, World!") // <-- This is a View
  .padding(10)        // <-- This is a modifier of that View

flutterUIコンポーネントを次のように表しますウィジェット

ビューとウィジェットはどちらも、変更が必要になるまでのみ存在します。 これらの言語ではこのプロパティを呼び出します不変性。 SwiftUI は、UI コンポーネントのプロパティを View 修飾子として表します。 対照的に、Flutter は UI コンポーネントと 彼らの特性。

Padding(                         // <-- This is a Widget
  padding: EdgeInsets.all(10.0), // <-- So is this
  child: Text("Hello, World!"),  // <-- This, too
)));

レイアウトを構成するには、SwiftUI と Flutter の両方が UI コンポーネントをネストします お互いの中で。 SwiftUI はビューをネストし、Flutter はウィジェットをネストします。

レイアウトプロセス

SwiftUI次のプロセスを使用してビューをレイアウトします。

  1. 親ビューは、子ビューにサイズを提案します。
  2. 後続のすべての子ビュー:
    • ~にサイズを提案する彼らの子どもの視点
    • その子にどのサイズが欲しいかを尋ねます
  3. 各親ビューは、返されたサイズで子ビューをレンダリングします。

flutterそのプロセスは多少異なります。

  1. 親ウィジェットは制約をその子に渡します。 制約には、高さと幅の最小値と最大値が含まれます。
  2. 子供は自分の大きさを決めようとします。独自の子のリストを使用して同じプロセスを繰り返します。
    • 子の制約を子に通知します。
    • それは子供にどのくらいのサイズになりたいかを尋ねます。
  3. 親が子を配置します。
    • 要求されたサイズが制約内に収まる場合、 親はそのサイズを使用します。
    • 要求されたサイズが制約に適合しない場合は、 親が高さ、幅、またはその両方を制限します。 その制約。

Flutter は、親コンポーネントがオーバーライドできるため、SwiftUI とは異なります。 子供の希望サイズ。ウィジェットは希望するサイズにすることはできません。 また、親としての画面上の位置を認識したり決定したりすることもできません。 その決定を下します。

子ウィジェットを強制的に特定のサイズでレンダリングするには、 親は厳しい制約を設定する必要があります。 制約の最小サイズ値を超えると制約が厳しくなります 最大サイズ値と等しくなります。

SwiftUI、ビューは利用可能なスペースまで拡張される可能性があります。 サイズをそのコンテンツのサイズに制限します。 flutterウィジェットも同様に動作します。

ただし、Flutter では、親ウィジェットは無制限の制約を提供できます。 無制限の制約では、最大値が無限大に設定されます。

UnboundedBox(
  child: Container(
      width: double.infinity, height: double.infinity, color: red),
)

子が展開され、無制限の制約がある場合、 Flutter はオーバーフロー警告を返します。

UnconstrainedBox(
  child: Container(color: red, width: 4000, height: 50),
)

When parents pass unbounded constraints to children, and the children are expanding, then there is an overflow warning

Flutter で制約がどのように機能するかを学ぶには、 見る制約を理解する

デザインシステム

Flutter は複数のプラットフォームをターゲットとしているため、アプリには あらゆる設計システムに準拠します。 このガイドの特徴ですが、材料ウィジェット、 Flutter アプリではさまざまなデザイン システムを使用できます。

  • カスタムマテリアルウィジェット
  • コミュニティが構築したウィジェット
  • 独自のカスタムウィジェット
  • クパチーノのウィジェットApple のヒューマン インターフェイス ガイドラインに準拠したもの

を備えた優れたリファレンス アプリをお探しの場合は、 カスタム デザイン システム、チェックアウト素晴らしい。

UIの基本

このセクションでは、UI 開発の基本について説明します。 Flutter と SwiftUI との比較。 これには、アプリの開発を開始する方法、静的テキストを表示する方法、 ボタンの作成、オンプレス イベントへの反応、リスト、グリッドなどの表示。

入門

SwiftUI、 あなたが使うAppアプリを起動します。

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            HomePage()
        }
    }
}

もう 1 つの一般的な SwiftUI プラクティスでは、アプリ本体をstructに準拠するものView次のようなプロトコル:

struct HomePage: View {
  var body: some View {
    Text("Hello, World!")
  }
}

を始めるには flutterapp、アプリのインスタンスをに渡します のrunApp関数。

void main() {
  runApp(const MyApp());
}

Appウィジェットです。 build メソッドは、 それが表すユーザーインターフェイス。 アプリを次で始めるのが一般的ですWidgetAppクラス、 好きCupertinoApp

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    // Returns a CupertinoApp that, by default,
    // has the look and feel of an iOS app.
    return const CupertinoApp(
      home: HomePage(),
    );
  }
}

で使用されるウィジェットHomePageから始まるかもしれませんScaffoldクラス。Scaffoldアプリの基本的なレイアウト構造を実装します。

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'Hello, World!',
        ),
      ),
    );
  }
}

Flutter がどのように使用するかに注目してください。Centerウィジェット。 SwiftUI は、デフォルトでビューのコンテンツを中央にレンダリングします。 Flutter では必ずしもそうとは限りません。Scaffoldレンダリングされませんbody画面中央のウィジェット。 テキストを中央に配置するには、テキストをCenterウィジェット。 さまざまなウィジェットとそのデフォルトの動作について詳しくは、以下をご覧ください。 のウィジェットカタログ

ボタンの追加

SwiftUIを使用します。Buttonボタンを作成するための構造体。

Button("Do something") {
  // this closure gets called when your
  // button is tapped
}

同じ結果を達成するには flutter、 使用CupertinoButtonクラス:

        CupertinoButton(
  onPressed: () {
    // This closure is called when your button is tapped.
  },
  child: const Text('Do something'),
)

flutter事前定義されたスタイルを持つさまざまなボタンにアクセスできます。 のCupertinoButtonクラスはクパチーノ図書館からのものです。 クパチーノ ライブラリのウィジェットは Apple のデザイン システムを使用しています。

コンポーネントを水平方向に整列させる

SwiftUI, スタック ビューは、レイアウトの設計において大きな役割を果たします。 2 つの別個の構造により、スタックを作成できます。

  1. HStack水平スタックビューの場合

  2. VStack垂直スタックビューの場合

次の SwiftUI ビューは地球儀の画像を追加し、 テキストを水平スタックビューに変換します。

HStack {
  Image(systemName: "globe")
  Text("Hello, world!")
}

flutter用途RowそれよりもHStack:

    Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Icon(CupertinoIcons.globe),
    Text('Hello, world!'),
  ],
),

RowウィジェットにはList<Widget>の中にchildrenパラメータ。 のmainAxisAlignmentプロパティは Flutter に子の配置方法を指示します 余分なスペースあり。MainAxisAlignment.center子どもたちを 主軸の中心。ためにRow、主軸は水平です 軸。

コンポーネントを垂直方向に整列させる

次の例は、前のセクションの例に基づいています。

SwiftUI、 あなたが使うVStackコンポーネントを配置して 垂直の柱。

VStack {
  Image(systemName: "globe")
  Text("Hello, world!")
}

flutter前の例と同じ Dart コードを使用します。 交換することを除いてColumnためにRow:

    Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Icon(CupertinoIcons.globe),
    Text('Hello, world!'),
  ],
),

リストビューの表示

SwiftUIを使用します。Listシーケンスを表示するための基本コンポーネント アイテムの。 一連のモデル オブジェクトを表示するには、ユーザーが次の操作を実行できることを確認してください。 モデルオブジェクトを特定します。 オブジェクトを識別できるようにするには、0a9c74dc-​​5d94-4ec0-9c82-e1247b7b675eプロトコル。

struct Person: Identifiable {
  var name: String
}

var persons = [
  Person(name: "Person 1"),
  Person(name: "Person 2"),
  Person(name: "Person 3"),
]

struct ListWithPersons: View {
  let persons: [Person]
  var body: some View {
    List {
      ForEach(persons) { person in
        Text(person.name)
      }
    }
  }
}

これはどのように似ていますか flutterリスト ウィジェットを構築することを好みます。 Flutter では、リスト項目を識別できる必要はありません。 表示するアイテムの数を設定し、各アイテムのウィジェットを構築します。

class Person {
  String name;
  Person(this.name);
}

var items = [
  Person('Person 1'),
  Person('Person 2'),
  Person('Person 3'),
];

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(items[index].name),
          );
        },
      ),
    );
  }
}

Flutter にはリストに関するいくつかの注意事項があります。

  • ListViewウィジェットにはビルダーメソッドがあります。 これは次のように機能しますForEachSwiftUI内でList構造体。

  • itemCountのパラメータListViewアイテムの数を設定します のListViewと表示されます。

  • itemBuilderゼロの間のインデックスパラメータがあります itemCount より 1 つ少ない値。

前の例では、ListTile各アイテムのウィジェット。 のListTileウィジェットには次のようなプロパティが含まれますheightfont-size。 これらのプロパティはリストの作成に役立ちます。ただし、Flutter では戻ることができます。 データを表すほぼすべてのウィジェット。

グリッドを表示する

無条件グリッドを構築する場合SwiftUI、 あなたが使うGridGridRow

Grid {
  GridRow {
    Text("Row 1")
    Image(systemName: "square.and.arrow.down")
    Image(systemName: "square.and.arrow.up")
  }
  GridRow {
    Text("Row 2")
    Image(systemName: "square.and.arrow.down")
    Image(systemName: "square.and.arrow.up")
  }
}

グリッドを表示するには flutter、 使用GridViewウィジェット。 このウィジェットにはさまざまなコンストラクターがあります。各コンストラクターには、 同様の目標ですが、異なる入力パラメータを使用します。 次の例では、.builder()イニシャライザ:

const widgets = [
  Text('Row 1'),
  Icon(CupertinoIcons.arrow_down_square),
  Icon(CupertinoIcons.arrow_up_square),
  Text('Row 2'),
  Icon(CupertinoIcons.arrow_down_square),
  Icon(CupertinoIcons.arrow_up_square),
];

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          mainAxisExtent: 40,
        ),
        itemCount: widgets.length,
        itemBuilder: (context, index) => widgets[index],
      ),
    );
  }
}

SliverGridDelegateWithFixedCrossAxisCount代表者が決定する グリッドがコンポーネントをレイアウトするために使用するさまざまなパラメーター。 これもcrossAxisCountそれがアイテムの数を決定します 各行に表示されます。

SwiftUIの仕組みGridそして flutterさんGridViewその点で違いますGrid必要GridRowGridViewデリゲートを使用して、 グリッドはそのコンポーネントをレイアウトする必要があります。

スクロールビューの作成

SwiftUI、 あなたが使うScrollViewカスタムスクロールを作成するには コンポーネント。 次の例では、一連のPersonViewインスタンス スクロール可能な方法で。

ScrollView {
  VStack(alignment: .leading) {
    ForEach(persons) { person in
      PersonView(person: person)
    }
  }
}

スクロールビューを作成するには、 flutter用途SingleChildScrollView。 次の例では、関数mockPersonインスタンスをモックする のPersonカスタムを作成するクラスPersonViewウィジェット。

    SingleChildScrollView(
  child: Column(
    children: mockPersons
        .map(
          (person) => PersonView(
            person: person,
          ),
        )
        .toList(),
  ),
),

レスポンシブでアダプティブなデザイン

SwiftUI、 あなたが使うGeometryReader相対的なビュー サイズを作成します。

たとえば、次のようなことができます。

  • かけるgeometry.size.width何らかの要因によって、
  • 使用GeometryReaderアプリのデザインを変更するためのブレークポイントとして使用します。

サイズクラスが次のとおりであるかどうかも確認できます。.regularまた.compact使用してhorizontalSizeClass

相対ビューを作成するには flutter、次の 2 つのオプションのいずれかを使用できます。

  • を入手BoxConstraints内のオブジェクトLayoutBuilderクラス。
  • 使用MediaQuery.of()ビルド関数内で 現在のアプリのサイズと向きを取得します。

さらに詳しく知りたい場合は、こちらをご覧くださいレスポンシブで適応性のあるアプリの作成

状態の管理

SwiftUIを使用します。@Stateを表すプロパティ ラッパー SwiftUI ビューの内部状態。

struct ContentView: View {
  @State private var counter = 0;
  var body: some View {
    VStack{
      Button("+") { counter+=1 }
      Text(String(counter))
    }
  }}

SwiftUIより複雑な状態のためのいくつかのオプションも含まれています などの管理ObservableObjectプロトコル。

flutterを使用してローカル状態を管理しますStatefulWidget。 次の 2 つのクラスを使用してステートフル ウィジェットを実装します。

  • のサブクラスStatefulWidget
  • のサブクラスState

Stateオブジェクトはウィジェットの状態を保存します。 ウィジェットの状態を変更するには、次のように呼び出します。setState()からStateサブクラス フレームワークにウィジェットを再描画するように指示します。

次の例は、カウンター アプリの一部を示しています。

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('$_counter'),
            TextButton(
              onPressed: () => setState(() {
                _counter++;
              }),
              child: const Text('+'),
            ),
          ],
        ),
      ),
    );
  }
}

状態を管理するその他の方法については、以下を参照してください。状態管理

アニメーション

UI アニメーションには主に 2 つのタイプがあります。

  • 現在の値から新しいターゲットまでアニメーション化することを暗黙的に示します。
  • 尋ねられたときにアニメーション化する明示的。

暗黙的なアニメーション

SwiftUI と Flutter はアニメーションに対して同様のアプローチを採用しています。 どちらのフレームワークでも、次のようなパラメータを指定します。duration、 とcurve

SwiftUIを使用します。animate()暗黙的に処理する修飾子 アニメーション。

Button(Tap me!){
   angle += 45
}
.rotationEffect(.degrees(angle))
.animation(.easeIn(duration: 1))

flutter暗黙的なアニメーション用のウィジェットが含まれています。 これにより、一般的なウィジェットのアニメーション化が簡素化されます。 Flutter は、これらのウィジェットに次の形式で名前を付けます。AnimatedFoo

例: ボタンを回転するには、AnimatedRotationクラス。 これによりアニメーション化されます。Transform.rotateウィジェット。

    AnimatedRotation(
  duration: const Duration(seconds: 1),
  turns: turns,
  curve: Curves.easeIn,
  child: TextButton(
      onPressed: () {
        setState(() {
          turns += .125;
        });
      },
      child: const Text('Tap me!')),
),

Flutter を使用すると、カスタムの暗黙的アニメーションを作成できます。 新しいアニメーション ウィジェットを作成するには、TweenAnimationBuilder

明示的なアニメーション

露骨なアニメーションの場合、SwiftUIを使用しますwithAnimation()関数。

flutter名前がフォーマットされた明示的にアニメーション化されたウィジェットが含まれます 好きFooTransition。 一例としては、RotationTransitionクラス。

Flutter を使用すると、カスタムの明示的なアニメーションを作成することもできます。AnimatedWidgetまたAnimatedBuilder

Flutter のアニメーションの詳細については、を参照してください。アニメーションの概要

画面上に描画する

SwiftUI、 あなたが使うCoreGraphics線や形を描くには 画面。

flutterに基づく API があります。Canvasクラス、 描画に役立つ 2 つのクラスがあります。

  1. CustomPaintそれにはペインターが必要です:

        CustomPaint(
       painter: SignaturePainter(_points),
       size: Size.infinite,
     ),
  2. ベッド4212f-e711-4703-a21d-e0d1e4902677キャンバスに描画するアルゴリズムを実装します。

    class SignaturePainter extends CustomPainter {
       SignaturePainter(this.points);
    
       final List<Offset?> points;
    
       @override
       void paint(Canvas canvas, Size size) {
         final Paint paint = Paint()
           ..color = Colors.black
           ..strokeCap = StrokeCap.round
           ..strokeWidth = 5;
         for (int i = 0; i < points.length - 1; i++) {
           if (points[i] != null && points[i + 1] != null) {
             canvas.drawLine(points[i]!, points[i + 1]!, paint);
           }
         }
       }
    
       @override
       bool shouldRepaint(SignaturePainter oldDelegate) =>
           oldDelegate.points != points;
     }

このセクションでは、アプリのページ間を移動する方法について説明します。 プッシュ&ポップ機構など。

開発者は、と呼ばれるさまざまなページを使用して iOS および macOS アプリを構築します。ナビゲーションルート

SwiftUINavigationStackこのページのスタックを表します。

次の例では、人物のリストを表示するアプリを作成します。 新しいナビゲーション リンクに個人の詳細を表示するには、 その人をタップします。

NavigationStack(path: $path) {
      List {
        ForEach(persons) { person in
          NavigationLink(
            person.name,
            value: person
          )
        }
      }
      .navigationDestination(for: Person.self) { person in
        PersonView(person: person)
      }
    }

小さいものがある場合は、 flutter複雑なリンクを必要としないアプリ、 使用Navigator名前付きルートを使用します。 ナビゲーションルートを定義したら、 名前を使用してナビゲーション ルートを呼び出します。

  1. に渡されるクラス内の各ルートに名前を付けます。runApp()関数。 次の例では、App:

    // Defines the route name as a constant
     // so that it's reusable.
     const detailsPageRouteName = '/details';
    
     class App extends StatelessWidget {
       const App({
         super.key,
       });
    
       @override
       Widget build(BuildContext context) {
         return CupertinoApp(
           home: const HomePage(),
           // The [routes] property defines the available named routes
           // and the widgets to build when navigating to those routes.
           routes: {
             detailsPageRouteName: (context) => const DetailsPage(),
           },
         );
       }
     }

    次のサンプルは、次を使用して人のリストを生成します。mockPersons()。人物をタップすると、その人物の詳細ページが表示されます にNavigator使用してpushNamed()

        ListView.builder(
       itemCount: mockPersons.length,
       itemBuilder: (context, index) {
         final person = mockPersons.elementAt(index);
         final age = '${person.age} years old';
         return ListTile(
           title: Text(person.name),
           subtitle: Text(age),
           trailing: const Icon(
             Icons.arrow_forward_ios,
           ),
           onTap: () {
             // When a [ListTile] that represents a person is
             // tapped, push the detailsPageRouteName route
             // to the Navigator and pass the person's instance
             // to the route.
             Navigator.of(context).pushNamed(
               detailsPageRouteName,
               arguments: person,
             );
           },
         );
       },
     ),
  2. を定義しますDetailsPage詳細を表示するウィジェット 各人。 Flutter では、引数を 新しいルートに移動するときのウィジェット。 次を使用して引数を抽出しますModalRoute.of():

    class DetailsPage extends StatelessWidget {
       const DetailsPage({super.key});
    
       @override
       Widget build(BuildContext context) {
         // Read the person instance from the arguments.
         final Person person = ModalRoute.of(
           context,
         )?.settings.arguments as Person;
         // Extract the age.
         final age = '${person.age} years old';
         return Scaffold(
           // Display name and age.
           body: Column(children: [Text(person.name), Text(age)]),
         );
       }
     }

より高度なナビゲーションとルーティングの要件を作成するには、 次のようなルーティング パッケージを使用します。go_router。

さらに詳しく知りたい場合は、こちらをご覧くださいナビゲーションとルーティング

手動でポップバックする

SwiftUIを使用します。dismissポップバック先の環境値 前の画面。

Button("Pop back") {
        dismiss()
      }

flutter、 使用pop()の機能Navigatorクラス:

TextButton(
  onPressed: () {
    // This code allows the
    // view to pop back to its presenter.
    Navigator.of(context).pop();
  },
  child: const Text('Pop back'),
),

SwiftUIを使用します。openURLを開くための環境変数 別のアプリケーションへの URL。

@Environment(\.openURL) private var openUrl

// View code goes here

 Button("Open website") {
      openUrl(
        URL(
          string: "https://google.com"
        )!
      )
    }

flutter、 使用url_launcherプラグイン。

    CupertinoButton(
  onPressed: () async {
    await launchUrl(
      Uri.parse('https://google.com'),
    );
  },
  child: const Text(
    'Open website',
  ),
),

テーマ、スタイル、メディア

少しの労力で Flutter アプリのスタイルを設定できます。 スタイリングには、明るいテーマと暗いテーマの切り替えが含まれます。 テキストと UI コンポーネントのデザインを変更する もっと。このセクションでは、アプリのスタイルを設定する方法について説明します。

ダークモードの使用

SwiftUI、あなたはpreferredColorScheme()の関数Viewダークモードを使用するには。

flutter、アプリレベルでライトモードとダークモードを制御できます。 明るさモードを制御するには、theme財産 のAppクラス:

    CupertinoApp(
  theme: CupertinoThemeData(
    brightness: Brightness.dark,
  ),
  home: HomePage(),
);

テキストのスタイル設定

SwiftUIでは、修飾子関数を使用してテキストのスタイルを設定します。 たとえば、フォントを変更するには、Text弦、 使用font()修飾子:

Text("Hello, world!")
  .font(.system(size: 30, weight: .heavy))
  .foregroundColor(.yellow)

テキストのスタイルを設定するには flutter、を追加しますTextStyle値としてのウィジェット のstyleのパラメータTextウィジェット。

    Text(
  'Hello, world!',
  style: TextStyle(
    fontSize: 30,
    fontWeight: FontWeight.bold,
    color: CupertinoColors.systemYellow,
  ),
),

ボタンのスタイリング

SwiftUIでは、修飾関数を使用してボタンのスタイルを設定します。

Button("Do something") {
    // do something when button is tapped
  }
  .font(.system(size: 30, weight: .bold))
  .background(Color.yellow)
  .foregroundColor(Color.blue)
}

ボタン ウィジェットのスタイルを設定するには flutter、その子のスタイルを設定し、 またはボタン自体のプロパティを変更します。

次の例では:

  • colorの財産CupertinoButtonを設定しますcolor
  • color子供の財産Textウィジェットはボタンを設定します テキストの色。
child: CupertinoButton(
  color: CupertinoColors.systemYellow,
  onPressed: () {},
  padding: const EdgeInsets.all(16),
  child: const Text(
    'Do something',
    style: TextStyle(
      color: CupertinoColors.systemBlue,
      fontSize: 30,
      fontWeight: FontWeight.bold,
    ),
  ),
),

カスタムフォントの使用

SwiftUI、2 つの手順でアプリでカスタム フォントを使用できます。 まず、フォント ファイルを SwiftUI プロジェクトに追加します。ファイルを追加した後、 使用.font()修飾子を使用して UI コンポーネントに適用します。

Text("Hello")
  .font(
    Font.custom(
      "BungeeSpice-Regular",
      size: 40
    )
  )

flutter、ファイルでリソースを制御します 名前付きpubspec.yaml。このファイルはプラットフォームに依存しません。 プロジェクトにカスタム フォントを追加するには、次の手順に従います。

  1. という名前のフォルダーを作成しますfontsプロジェクトのルートディレクトリにあります。 このオプションの手順は、フォントを整理するのに役立ちます。
  2. を追加してください.ttf.otf、 また.ttcフォントファイルをfontsフォルダ。
  3. を開きますpubspec.yamlプロジェクト内のファイル。
  4. を見つけるflutterセクション。
  5. カスタム フォントをfontsセクション。

     flutter:
       fonts:
         - family: BungeeSpice
           fonts:
             - asset: fonts/BungeeSpice-Regular.ttf
    

プロジェクトにフォントを追加すると、次のように使用できます。 次の例:

        Text(
  'Cupertino',
  style: TextStyle(
    fontSize: 40,
    fontFamily: 'BungeeSpice',
  ),
)

アプリ内に画像をバンドルする

SwiftUI、最初に画像ファイルを追加しますAssets.xcassets、 次に、を使用しますImageビューを使用して画像を表示します。

画像を追加するには flutter、追加した方法と同様の方法に従います。 カスタムフォント。

  1. を追加imagesフォルダをルートディレクトリにコピーします。
  2. このアセットをpubspec.yamlファイル。

     flutter:
       assets:
         - images/Blueberries.jpg
    

画像を追加したら、Imageウィジェットの.asset()コンストラクタ。このコンストラクター:

  1. 指定されたパスを使用して、指定されたイメージをインスタンス化します。
  2. アプリにバンドルされているアセットから画像を読み取ります。
  3. 画像を画面に表示します。

完全な例を確認するには、以下を確認してください。Imageドキュメント。

アプリにビデオをバンドルする

SwiftUI、ローカルビデオファイルをアプリに2つにバンドルします ステップ。 まず、インポートしますAVKitフレームワークを作成してから、VideoPlayer意見。

flutterを追加します。ビデオプレーヤープラグインをプロジェクトに追加します。 このプラグインを使用すると、上で動作するビデオプレーヤーを作成できます。 Android、iOS、Web 上で同じコードベースから動作します。

  1. プラグインをアプリに追加し、ビデオ ファイルをプロジェクトに追加します。
  2. アセットをpubspec.yamlファイル。
  3. 使用VideoPlayerControllerビデオをロードして再生するクラス ファイル。

完全なチュートリアルを確認するには、video_player の例。